package com.jsftoolkit.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * The underlying {@link FileOutputStream} is not created until it is first
 * written to. If no bytes are written, the file remains unchanged.
 * <p>
 * Useful when you need to read in a file and write it back out, but need to
 * create both streams before first reading, to avoid clobbering the file.
 * 
 * @author noah
 * 
 */
public class DeferedFileOutputStream extends DelegatingOutputStream {

	private final File file;

	private FileOutputStream out;

	/**
	 * Convenience constructor, calls {@link File#File(String)}.
	 * 
	 * @param filename
	 */
	public DeferedFileOutputStream(final String filename) {
		this(new File(filename));
	}

	/**
	 * Creates a new instance for the given file.
	 * 
	 * @param file
	 */
	public DeferedFileOutputStream(final File file) {
		super();
		this.file = file;
	}

	/**
	 * Lazily initializes the output stream.
	 */
	@Override
	protected OutputStream getStream() throws IOException {
		if (out == null) {
			out = new FileOutputStream(file);
		}
		return out;
	}

	/**
	 * If the underlying stream has been created, flushes it. Otherwise, does
	 * nothing.
	 */
	@Override
	public void flush() throws IOException {
		if (null != out) {
			super.flush();
		}
	}

	/**
	 * If the underlying stream has been created, closes it. Otherwise does
	 * nothing.
	 */
	@Override
	public void close() throws IOException {
		if (out != null) {
			super.close();
		}
	}
}
